/**
 * 插件工具方法
 */
import { sendToBackground } from "@plasmohq/messaging"
import type { PlasmoMessaging } from "@plasmohq/messaging"
import { Storage } from "@plasmohq/storage"

// 定义店铺信息类型
export interface ShopInfo {
  // 店铺id
  id: number
  // 店铺名称
  name: string
  // 店铺类型
  src: string
}

/**
 *  快捷请求background的服务
 *  @param api api名称
 *  @param data 服务参数
 *  @param serverName 服务名称,默认为 apiService
 */
// 服务名称
const apiServiceName = "apiService"
export const _callApi = async (api: string, data: any, serverName?: string) => {
  const req = {
    name: serverName || apiServiceName,
    body: {
      api: api,
      data: data
    }
  } as PlasmoMessaging.Request<never, { api: string; data?: any }>
  return await sendToBackground(req)
}

/**
 * 获取用户登陆状态
 */
export const isLogin = async () => {
  const storage = new Storage()
  const isLogin = await storage.get("isLogin")
  return !!isLogin
}

/**
 * 用户登录信息获取
 */
export const getUserInfo = async (key: string) => {
  const storage = new Storage()
  const loginInfo = await storage.get("loginInfo")
  // 返回用户信息对应key的值,如果不存在返回空字符串
  return loginInfo ? loginInfo[key] || "" : ""
}

/**
 * 用户店铺列表
 * 集成主店铺和工作店铺
 */
export const getUserShopList = async () => {
  // 如果未登录，返回空数组
  if (!(await isLogin())) {
    return [] as ShopInfo[]
  }
  // 获取主店铺
  const mainShop: ShopInfo = await getUserInfo("prefix")
  // 工作店铺列表
  const workShopList: [ShopInfo] = (await getUserInfo("actionshop")) || []
  const workShopList2: [ShopInfo] = (await getUserInfo("workprefix")) || []
  // 合并主店铺和工作店铺，去重，获得店铺列表
  const shopList = [mainShop, ...workShopList, ...workShopList2].reduce(
    (acc, cur) => {
      const isExist = acc.some((item) => item.id === cur.id)
      if (!isExist) {
        acc.push(cur)
      }
      return acc
    },
    [] as ShopInfo[]
  )
  // 按id排序
  return shopList.sort((a, b) => a.id - b.id)
}

/**
 * 将base64转换为Blob对象
 * @param dataURI
 */
export const dataURItoBlob = (dataURI: string) => {
  // 解析dataURI以获取Base64编码的部分
  const base64 = dataURI.split(",")[1]

  // 解码Base64字符串
  const binaryString = atob(base64)

  // 将二进制字符串转换为8位无符号整数数组
  const byteArray = new Uint8Array(binaryString.length)
  for (let i = 0; i < binaryString.length; i++) {
    byteArray[i] = binaryString.charCodeAt(i)
  }

  // 从dataURI中获取MIME类型
  const mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0]

  // 创建Blob对象
  return new Blob([byteArray], { type: mimeString })
}

/**
 * 根据URL获取平台类型
 * @param url
 * @returns 平台类型
 */
export const getPlatform = (url: string): string => {
  // 三个平台的对应key_url定义
  const platformMap = {
    dy: "compass.jinritemai.com",
    tb: "market.m.taobao.com",
    ks: "zs.kwaixiaodian.com",
    wxsp: "channels.weixin.qq.com"
  }
  // 判断url是否包含平台key_url,并返回平台名称
  for (const key in platformMap) {
    if (url.includes(platformMap[key])) {
      return key
    }
  }
  return ""
}

// 等待查询元素方法
export function waitForElements(
  selector: string,
  timeoutSecond?: number
): Promise<NodeListOf<Element>> {
  const _timeoutSecond = timeoutSecond || 30
  return new Promise((resolve) => {
    const observer = new MutationObserver((mutations) => {
      for (const mutation of mutations) {
        if (mutation.type === "childList") {
          const elements = document.querySelectorAll(selector)
          if (elements.length > 0) {
            observer.disconnect()
            resolve(elements)
          }
        }
      }
    })
    observer.observe(document.body, { childList: true, subtree: true })
    // 设置超时定时器
    const timeoutId = setTimeout(() => {
      observer.disconnect()
      resolve([] as unknown as NodeListOf<Element>)
    }, _timeoutSecond * 1000)
  })
}
